#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include <sys/types.h>
#include "channel.h"
#include "task.hpp"
#include <ctime>
#include <stdlib.h>


void CreatSubprocess(int& processnum, std::vector<channel>& channels, task_t task)
{
    for (int i = 0; i < processnum; ++i)
    {
        int pipefd[2];
        int n = pipe(pipefd);
        if (n < 0)
        {
            perror("pipe");
            exit(-1);
        }

        pid_t id = fork();
        if (id == 0)
        { 
            if (!channels.empty())
            {
                for (auto& e : channels)
                    e.Close();
            }
            close(pipefd[1]);
            dup2(pipefd[0], 0);// 重定向
            task();
            exit(0);
        }
        close(pipefd[0]);
        std::string channelName = "channel" + std::to_string(i);
        channels.push_back(channel(pipefd[1], id, channelName));
    }
}

void CtrlProcessOnce(std::vector<channel>& channels)
{
    TaskInit();
    while (true)
    {
        sleep(1);
        CtrlProcess(channels);
    }
}

void CleanChannel(std::vector<channel>& channels)
{
    // int num = channels.size() - 1;
    // while (num >= 0)
    // {
    //     channels[num].Close();
    //     channels[num--].Wait();
    // }
    for (auto& e : channels)
    {
        e.Close();
        e.Wait();
    }
}

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        std::cerr << "Place input processnum." << std::endl;
    }

    std::vector<channel> channels;

    int processnum = std::stoi(argv[1]);

    // 1. 创建子进程
    CreatSubprocess(processnum, channels, work);

    // 2. 控制子进程
    CtrlProcessOnce(channels);

    // 3. 回收管道和子进程
    CleanChannel(channels);

    return 0;
}
